﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text.RegularExpressions;
using RoketSolutions.SP2010.Infrostructure.UI.Ajax.Abstractions;
using RoketSolutions.SP2010.Infrostructure.UI.Ajax.ValueProviders.Interfaces;
using RoketSolutions.SP2010.Infrostructure.Common.Extensions;
using System.Linq;

namespace RoketSolutions.SP2010.Infrostructure.UI.Ajax.ValueProviders
{
    public class FormValueProviderFactory : ValueProviderFactory
    {
        public override IValueProvider CreateProvider(ControllerContext controllerContext)
        {
            if (controllerContext == null)
                throw new ArgumentNullException("controllerContext");

            return new FormValueProvider(controllerContext);
        }
    }

    public class FormValueProvider : IValueProvider
    {
        public FormValueProvider(ControllerContext controllerContext)
        {
            FormValues = controllerContext.HttpContext.Request.Form;
        }

        protected NameValueCollection FormValues { get; set; }

        public bool ContainsPrefix(string key)
        {
            return ContainsPrefix(key, true);
        }

        public bool ContainsPrefix(string key, bool matchExact)
        {
            return matchExact
                       ? FormValues.AllKeys.Contains(key, true)
                       : FormValues.AllKeys.Any(item => item.StartsWith(key, StringComparison.InvariantCultureIgnoreCase));
        }

        public bool ContainsMatchPrefix(string keyPattern)
        {
            var exp = new Regex(keyPattern, RegexOptions.IgnoreCase);
            return FormValues.AllKeys.Any(exp.IsMatch);
        }

        public List<string> GetMatchPrefix(string keyPattern)
        {
            var exp = new Regex(keyPattern, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
            var result = new List<string>();

            for (var i = 0; i < FormValues.Count; i++)
            {
                var match = exp.Match(FormValues.GetKey(i));
                if (match.Success && !result.Contains(match.Value))
                {
                    result.Add(match.Value);
                }
            }

            return result;
        }

        public ValueProviderResult GetValue(string key)
        {
            var values = FormValues.GetValues(key);
            var value = FormValues.Get(key);
            return new ValueProviderResult(values, value);
        }

    }
}